﻿using System;
using System.Net;
using System.Windows;
using System.Windows.Controls;
using System.Windows.Documents;
using System.Windows.Ink;
using System.Windows.Input;
using System.Windows.Media;
using System.Windows.Media.Animation;
using System.Windows.Shapes;
using System.Text;
using System.IO;
using System.Collections.Generic;

namespace SuperMessage.Service
{
    public class GBKEncoding
    {

        private GBKEncoding()
        {
            #region 加载GBKToUnicode.txt文件

            byte[] GBKBuffer;
            using (Stream fs = App.GetResourceStream(new Uri("/SuperMessage;component/Data/GBKToUnicode.txt", UriKind.Relative)).Stream)
            {
                GBKBuffer = new byte[fs.Length];
                fs.Read(GBKBuffer, 0, GBKBuffer.Length);
            }

            GBKToUnicode = new string[32191];
            for (int i = 3; i < GBKBuffer.Length; i = i + 11)
            {
                int key = Convert.ToInt32(Encoding.UTF8.GetString(GBKBuffer, i, 4), 16);
                string value = Encoding.UTF8.GetString(GBKBuffer, i + 5, 4);
                GBKToUnicode[key - 0x8140] = value;
            }

            #endregion

            #region 加载UnicodeToGBK.txt文件

            byte[] UnicodeBuffer;
            using (Stream fs = App.GetResourceStream(new Uri("/SuperMessage;component/Data/UnicodeToGBK.txt", UriKind.Relative)).Stream)
            {
                UnicodeBuffer = new byte[fs.Length];
                fs.Read(UnicodeBuffer, 0, UnicodeBuffer.Length);
            }

            UnicodeToGBKOne = new string[942];
            UnicodeToGBKTwo = new string[1587];
            UnicodeToGBKThree = new string[982];
            UnicodeToGBKFour = new string[20902];
            UnicodeToGBKFive = new string[158];
            UnicodeToGBKSix = new string[1722];
            for (int i = 3; i < UnicodeBuffer.Length; i = i + 11)
            {
                int key = Convert.ToInt32(Encoding.UTF8.GetString(UnicodeBuffer, i, 4), 16);
                string value = Encoding.UTF8.GetString(UnicodeBuffer, i + 5, 4);
                if (key >= 0x00A4 && key <= 0x0451)
                {
                    UnicodeToGBKOne[key - 0x00A4] = value;
                }
                else if (key >= 0x2010 && key <= 0x2642)
                {
                    UnicodeToGBKTwo[key - 0x2010] = value;
                }
                else if (key >= 0x3000 && key <= 0x33D5)
                {
                    UnicodeToGBKThree[key - 0x3000] = value;
                }
                else if (key >= 0x4E00 && key <= 0x9FA5)
                {
                    UnicodeToGBKFour[key - 0x4E00] = value;
                }
                else if (key >= 0xE7C7 && key <= 0xE864)
                {
                    UnicodeToGBKFive[key - 0xE7C7] = value;
                }
                else if (key >= 0xF92C && key <= 0xFFE5)
                {
                    UnicodeToGBKSix[key - 0xF92C] = value;
                }
            }

            #endregion
        }

        private static object syncRoot = new Object();
        private static GBKEncoding _instance;//单例设计模式
        public static GBKEncoding Instance
        {
            get
            {
                if (_instance == null)
                {
                    lock (syncRoot)
                    {
                        if (null == _instance)
                        {
                            _instance = new GBKEncoding();
                        }
                    }
                }
                return _instance;
            }
        }


        string[] GBKToUnicode;//0x8140--0xFEFE     32191个编码位零散分布着21886个GBK编码的中文字符
        /// <summary>
        /// 返回Unicode编码的字节数组
        /// </summary>
        /// <param name="GBKBytes">GBK编码的字节数组</param>
        /// <returns>Unicode编码的字节数组</returns>
        public byte[] GetUnicodeBytes(byte[] GBKBytes)
        {
            List<byte> UnicodeArray = new List<byte>();

            for (int i = 0; i < GBKBytes.Length; )
            {
                if (GBKBytes[i] < (byte)128)
                {
                    UnicodeArray.Add(GBKBytes[i]);
                    UnicodeArray.Add((byte)0);
                    i++;
                }
                else
                {
                    int key = Convert.ToInt32(GBKBytes[i].ToString("X2") + GBKBytes[i + 1].ToString("X2"), 16);
                    string value = GBKToUnicode[key - 0x8140];
                    if (value == null)
                    {

                    }
                    UnicodeArray.Add(Convert.ToByte(value.Substring(2, 2), 16));
                    UnicodeArray.Add(Convert.ToByte(value.Substring(0, 2), 16));
                    i = i + 2;
                }
            }

            return UnicodeArray.ToArray();
        }


        string[] UnicodeToGBKOne;//0x00A4--0x0451       942  个编码位零散分布着157  个Unicode编码的中文字符
        string[] UnicodeToGBKTwo;//0x2010--0x2642       1587 个编码位零散分布着289  个Unicode编码的中文字符
        string[] UnicodeToGBKThree;//0x3000--0x33D5     982  个编码位零散分布着270  个Unicode编码的中文字符
        string[] UnicodeToGBKFour;//0x4E00--0x9FA5      20902个编码位零散分布着20902个Unicode编码的中文字符
        string[] UnicodeToGBKFive;//0xE7C7--0xE864      158  个编码位零散分布着95   个Unicode编码的中文字符
        string[] UnicodeToGBKSix;//0xF92C--0xFFE5       1722 个编码位零散分布着173  个Unicode编码的中文字符
        /// <summary>
        /// 返回GBK编码的字节数组
        /// </summary>
        /// <param name="UnicodeBytes">Unicode编码的字节数组</param>
        /// <returns>GBK编码的字节数组</returns>
        public byte[] GetGBKBytes(byte[] UnicodeBytes)
        {
            List<byte> GBKArray = new List<byte>();
            for (int i = 0; i < UnicodeBytes.Length; i = i + 2)
            {
                if (UnicodeBytes[i] < (byte)128 && UnicodeBytes[i + 1] == 0)
                {
                    GBKArray.Add(UnicodeBytes[i]);
                }
                else
                {
                    int key = Convert.ToInt32(UnicodeBytes[i + 1].ToString("X2") + UnicodeBytes[i].ToString("X2"), 16);
                    string value = null;
                    if (key >= 0x00A4 && key <= 0x0451)
                    {
                        value = UnicodeToGBKOne[key - 0x00A4];
                    }
                    else if (key >= 0x2010 && key <= 0x2642)
                    {
                        value = UnicodeToGBKTwo[key - 0x2010];
                    }
                    else if (key >= 0x3000 && key <= 0x33D5)
                    {
                        value = UnicodeToGBKThree[key - 0x3000];
                    }
                    else if (key >= 0x4E00 && key <= 0x9FA5)
                    {
                        value = UnicodeToGBKFour[key - 0x4E00];
                    }
                    else if (key >= 0xE7C7 && key <= 0xE864)
                    {
                        value = UnicodeToGBKFive[key - 0xE7C7];
                    }
                    else if (key >= 0xF92C && key <= 0xFFE5)
                    {
                        value = UnicodeToGBKSix[key - 0xF92C];
                    }
                    else
                    {

                    }
                    if (value == null)
                    {

                    }
                    GBKArray.Add(Convert.ToByte(value.Substring(0, 2), 16));
                    GBKArray.Add(Convert.ToByte(value.Substring(2, 2), 16));
                }
            }

            return GBKArray.ToArray();
        }

    }
}
